gai_strerror() is not thread-safe on Windows#15568
Conversation
WSPiApi.h has been created in 2000, so we can safely assume that it is available everywhere nowadays. Furthermore, `gai_strerror()` is available regardless of whether there is IPv6 support.
|
FWIW, I brought up in GH-15555 about using |
|
Making IPv6 mandatory seems like a good idea, and would render this patch moot (if we require IPv6 for PHP 8.4, what might be a bit late), but the main point of this PR is to avoid calling |
|
Yeah, it's probably too late to get any v6 changes in for 8.4, but refactors that get us further there are still a good idea. |
We extract `report_getaddrinfo_failure()`, and refactor that further. While this code is now a tad bit slower, that shouldn't matter since it is error handling. We also cheat a bit, since adding a proper format specifier for `php_error_docref()` is not a proper refactoring, but more like a bug fix.
main/network.c
Outdated
| } else { | ||
| php_error_docref(NULL, E_WARNING, "php_network_getaddresses: getaddrinfo for %s failed: %s", host, PHP_GAI_STRERROR(n)); | ||
| } | ||
| report_getaddrinfo_failure(host, n, error_string); |
There was a problem hiding this comment.
The code in the } else if (res == NULL) { below could also call report_getaddrinfo_failure(), but the two legs have slightly different error messages: one shows errno, but not the other. I doubt that showing errno here is correct (since getaddrinfo() has apparently not failed, but I'm not sure. I'm not even sure if that code would ever be executed; isn't res supposed to be set if getaddrinfo() returns 0?
This reverts commit 7b151af2103216295ed82e87d38dae3663ddc35a.
First we refactor to have only a single usage of `PHP_GAI_STRERROR()` left; then we drop the macro in favor of calling the different functions conditionally in an ad-hoc style. This is necessary because the return value of `php_win32_error_to_msg` needs to be freed by the caller. The error messages are no more inline with other error messages, since `gai_strerror()` apparently always appends a period and a space.
This PR is mainly about avoiding
gai_strerror()on Windows, because the function is not thread-safe there[1].However, it also fixes the IPv6 configuration on Windows where
HAVE_GAI_STRERRORonly was defined if IPv6 support is requested (the default; can be disabled with--disable-ipv6), although that function is generally available. For BC, we defineHAVE_GAI_STRERRORbut do no longer use it internally. If extensions use it, they should be fixed (if necessary), but we don't want to break them that late in the pre-release cycle of PHP 8.4.Note that I'm fine with dropping the changes to config.w32, but the 5th commit should be merged (maybe in a different form; code is not nice as is).
[1] https://learn.microsoft.com/en-us/windows/win32/api/ws2tcpip/nf-ws2tcpip-gai_strerrora
WSPiApi.h has been created in 2000, so we can safely assume that it is available everywhere nowadays. Furthermore,
gai_strerror()is available regardless of whether there is IPv6 support.This came up in #15567, and solves the easy part. Not using
gai_strerror()on Windows, because it is not thread-safe would be as simple asdefine PHP_GAI_STRERROR(x) (php_win32_error_to_msg(x))if there wasn't a memory leak because the returned buffer needs to be freed by the caller. Any suggestions on how to solve this in a clean way are welcome!